package com.atguigu.schedule.controller;

import com.atguigu.schedule.common.Result;
import com.atguigu.schedule.pojo.*;
import com.atguigu.schedule.service.AutoRecordingService;
import com.atguigu.schedule.service.VideoRecordingService;
import com.atguigu.schedule.service.FFmpegRecordingService;
import com.atguigu.schedule.service.FileConversionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 录制管理控制器
 */
@RestController
@RequestMapping("/api/recording")
@RequiredArgsConstructor
@Slf4j
public class RecordingController {
    
    private final VideoRecordingService recordingService;
    private final AutoRecordingService autoRecordingService;
    private final FFmpegRecordingService ffmpegRecordingService;
    private final FileConversionService fileConversionService;
    
    /**
     * 按日期查询录制文件
     */
    @GetMapping("/by-date")
    public Result<List<RecordingResponse>> getRecordingsByDate(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        try {
            LocalDateTime startTime = startDate.atStartOfDay();
            LocalDateTime endTime = endDate.atTime(23, 59, 59);
            
            RecordingQueryRequest queryRequest = new RecordingQueryRequest();
            queryRequest.setStartDate(startTime);
            queryRequest.setEndDate(endTime);
            queryRequest.setStatus("COMPLETED");
            queryRequest.setSortBy("startTime");
            queryRequest.setSortOrder("asc");
            
            List<RecordingResponse> response = recordingService.getRecordings(queryRequest);
            
            return Result.ok(response);
            
        } catch (Exception e) {
            log.error("按日期查询录制文件失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "查询录制文件失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取录制文件的时间段信息
     */
    @GetMapping("/time-ranges")
    public Result<List<TimeRange>> getRecordingTimeRanges(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
        try {
            List<TimeRange> timeRanges = recordingService.getRecordingTimeRanges(date);
            return Result.ok(timeRanges);
            
        } catch (Exception e) {
            log.error("获取录制时间段失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "获取录制时间段失败: " + e.getMessage());
        }
    }
    
    /**
     * 开始录制
     */
    @PostMapping("/start")
    public Result<RecordingResponse> startRecording(@RequestBody StartRecordingRequest request) {
        try {
            RecordingResponse response = recordingService.startRecording(request);
            if (response != null) {
                return Result.ok(response);
            } else {
                return Result.build(null, 500, "开始录制失败");
            }
        } catch (Exception e) {
            log.error("开始录制失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "开始录制失败: " + e.getMessage());
        }
    }
    
    /**
     * 停止录制
     */
    @PostMapping("/stop/{recordingId}")
    public Result<String> stopRecording(@PathVariable Long recordingId) {
        try {
            boolean success = recordingService.stopRecording(recordingId);
            if (success) {
                return Result.ok("停止录制成功");
            } else {
                return Result.build(null, 500, "停止录制失败");
            }
        } catch (Exception e) {
            log.error("停止录制失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "停止录制失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取录制状态
     */
    @GetMapping("/status/{recordingId}")
    public Result<RecordingResponse> getRecordingStatus(@PathVariable Long recordingId) {
        try {
            RecordingResponse response = recordingService.getRecordingStatus(recordingId);
            return Result.ok(response);
        } catch (Exception e) {
            log.error("获取录制状态失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "获取录制状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询录制列表
     */
    @PostMapping("/query")
    public Result<List<RecordingResponse>> getRecordings(@RequestBody RecordingQueryRequest request) {
        try {
            List<RecordingResponse> response = recordingService.getRecordings(request);
            return Result.ok(response);
        } catch (Exception e) {
            log.error("查询录制列表失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "查询录制列表失败: " + e.getMessage());
        }
    }
    
    
    /**
     * 启动自动录制
     */
    @PostMapping("/auto/start")
    public Result<String> startAutoRecording() {
        try {
            autoRecordingService.startAutoRecording();
            return Result.ok("自动录制启动成功");
        } catch (Exception e) {
            log.error("启动自动录制失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "启动自动录制失败: " + e.getMessage());
        }
    }
    
    /**
     * 停止自动录制
     */
    @PostMapping("/auto/stop")
    public Result<String> stopAutoRecording() {
        try {
            autoRecordingService.stopAutoRecording();
            return Result.ok("自动录制停止成功");
        } catch (Exception e) {
            log.error("停止自动录制失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "停止自动录制失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取自动录制状态
     */
    @GetMapping("/auto/status")
    public Result<Map<String, Object>> getAutoRecordingStatus() {
        try {
            Map<String, Object> status = autoRecordingService.getAutoRecordingStatus();
            return Result.ok(status);
        } catch (Exception e) {
            log.error("获取自动录制状态失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "获取自动录制状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 检查FFmpeg是否可用
     */
    @GetMapping("/ffmpeg/status")
    public Result<Map<String, Object>> getFFmpegStatus() {
        try {
            boolean isAvailable = ffmpegRecordingService.isFFmpegAvailable();
            Map<String, Object> status = new HashMap<>();
            status.put("isAvailable", isAvailable);
            status.put("message", isAvailable ? "FFmpeg可用" : "FFmpeg不可用");
            return Result.ok(status);
        } catch (Exception e) {
            log.error("检查FFmpeg状态失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "检查FFmpeg状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取录制进程状态
     */
    @GetMapping("/process/status/{recordingId}")
    public Result<Map<String, Object>> getRecordingProcessStatus(@PathVariable Long recordingId) {
        try {
            Map<String, Object> status = ffmpegRecordingService.getRecordingProcessStatus(recordingId);
            return Result.ok(status);
        } catch (Exception e) {
            log.error("获取录制进程状态失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "获取录制进程状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 修复录制文件格式（将mp4.tmp转换为mp4）
     */
    @PostMapping("/fix-format/{recordingId}")
    public Result<String> fixRecordingFileFormat(@PathVariable Long recordingId) {
        try {
            String fixedPath = fileConversionService.fixRecordingFileFormat(recordingId);
            if (fixedPath != null) {
                return Result.ok("文件格式修复成功: " + fixedPath);
            } else {
                return Result.build(null, 404, "未找到需要修复的文件");
            }
        } catch (Exception e) {
            log.error("修复录制文件格式失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "修复录制文件格式失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量转换mp4.tmp文件
     */
    @PostMapping("/batch-convert")
    public Result<Map<String, Object>> batchConvertTmpFiles() {
        try {
            List<String> convertedFiles = fileConversionService.batchConvertTmpFiles("/recordings");
            Map<String, Object> result = new HashMap<>();
            result.put("convertedCount", convertedFiles.size());
            result.put("convertedFiles", convertedFiles);
            return Result.ok(result);
        } catch (Exception e) {
            log.error("批量转换文件失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "批量转换文件失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取所有mp4.tmp文件列表
     */
    @GetMapping("/tmp-files")
    public Result<List<Map<String, Object>>> getTmpFiles() {
        try {
            List<File> tmpFiles = fileConversionService.getTmpFiles("/recordings");
            List<Map<String, Object>> fileList = new ArrayList<>();
            
            for (File file : tmpFiles) {
                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("name", file.getName());
                fileInfo.put("path", file.getAbsolutePath());
                fileInfo.put("size", file.length());
                fileInfo.put("lastModified", file.lastModified());
                fileList.add(fileInfo);
            }
            
            return Result.ok(fileList);
        } catch (Exception e) {
            log.error("获取临时文件列表失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "获取临时文件列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试录制文件扫描
     */
    @GetMapping("/test-scan")
    public Result<Map<String, Object>> testScan() {
        try {
            String recordingsDir = "/usr/local/srs/srs/trunk/objs/nginx/html/recordings/live/livestream";
            File dir = new File(recordingsDir);
            
            Map<String, Object> result = new HashMap<>();
            result.put("directory", recordingsDir);
            result.put("exists", dir.exists());
            result.put("isDirectory", dir.isDirectory());
            
            if (dir.exists() && dir.isDirectory()) {
                File[] files = dir.listFiles((d, name) -> name.endsWith(".mp4") && !name.endsWith(".tmp"));
                result.put("mp4Files", files != null ? files.length : 0);
                
                List<Map<String, Object>> fileList = new ArrayList<>();
                if (files != null) {
                    for (File file : files) {
                        Map<String, Object> fileInfo = new HashMap<>();
                        fileInfo.put("name", file.getName());
                        fileInfo.put("size", file.length());
                        fileInfo.put("lastModified", file.lastModified());
                        fileList.add(fileInfo);
                    }
                }
                result.put("files", fileList);
            }
            
            return Result.ok(result);
        } catch (Exception e) {
            log.error("测试扫描失败: {}", e.getMessage(), e);
            return Result.build(null, 500, "测试扫描失败: " + e.getMessage());
        }
    }
}
